 package xin.petstore.framework.exception;
 
 import java.io.IOException;
 import java.util.Collections;
 import java.util.List;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;


 import org.springframework.http.HttpInputMessage;
 import org.springframework.http.HttpOutputMessage;
 import org.springframework.http.MediaType;
 import org.springframework.http.converter.HttpMessageConverter;
 import org.springframework.http.server.ServletServerHttpRequest;
 import org.springframework.http.server.ServletServerHttpResponse;
 import org.springframework.web.bind.annotation.ResponseBody;
 import org.springframework.web.method.HandlerMethod;
 import org.springframework.web.servlet.ModelAndView;
 import org.springframework.web.servlet.handler.AbstractHandlerMethodExceptionResolver;
 
 public class ResponseBodyHandlerExceptionResolver extends AbstractHandlerMethodExceptionResolver
 {
   private HttpMessageConverter messageConverter;
 
   @Override
   protected ModelAndView doResolveHandlerMethodException(HttpServletRequest request, HttpServletResponse response, HandlerMethod handlerMethod, Exception ex)
   {
     this.logger.error(request.getRequestURI(), ex);
     if (handlerMethod.getMethodAnnotation(ResponseBody.class) != null) {
       try {
         response.setStatus(500);
         return writeJson(request, response, new ErrorMessage(ex.getMessage()));
       } catch (IOException e) {
         this.logger.error(ex.getMessage(), e);
       }
     }
     return null;
   }
 
   private ModelAndView writeJson(HttpServletRequest request, HttpServletResponse response, Object value) throws IOException {
     HttpInputMessage inputMessage = new ServletServerHttpRequest(request);
     List<MediaType> acceptedMediaTypes = inputMessage.getHeaders().getAccept();
     if (acceptedMediaTypes.isEmpty()) {
       acceptedMediaTypes = Collections.singletonList(MediaType.ALL);
     }
     MediaType.sortByQualityValue(acceptedMediaTypes);
     HttpOutputMessage outputMessage = new ServletServerHttpResponse(response);
     Class returnValueType = value.getClass();
     for (MediaType acceptedMediaType : acceptedMediaTypes) {
       if (this.messageConverter.canWrite(returnValueType, acceptedMediaType)) {
         this.messageConverter.write(value, acceptedMediaType, outputMessage);
         return new ModelAndView();
       }
     }
     return null;
   }
 
   public void setMessageConverter(HttpMessageConverter messageConverter) {
     this.messageConverter = messageConverter;
   }
 }
